__PAIR3_START__ = 0x00
__PAIR3_END__   = 0x04

__NULL__        = 0x00
__ADD__         = 0x01
__SUBTRACT__    = 0x02
__MULTIPLY__    = 0x03
__DIVIDE__      = 0x04

__MOVE__        = 0x05

# Registers are used by the blocks to control the processing
__REG__         = 0x06
__PROGRAM__     = 0x00
__STREAM__      = 0x01

class block:

    # This is the inital setup of the block program for the block class
    def __init__(self, program, stream):
        self.program = program
        self.pointer = 0
        self.stream = stream

    # This preforms one instuction at a time
    def DoInstruction(self):
        data = self.GetByte(self.pointer)
        ins = data and 0xFF
        self.IncPointer(1)
        if ins >= __PAIR3_START__ and ins <= __PAIR3_END__:
            addr1 = self.ReadInt16(self.pointer)
            addr2 = self.ReadInt16(self.pointer)
            dest  = self.ReadInt16(self.pointer)
            self.IncPointer(4*3)
            if ins == __ADD__:
                self.WriteInt32(dest, self.ReadInt32(addr1) + self.ReadInt32(addr2))
            elif ins == __SUBTRACT__:
                self.WriteInt32(dest, self.ReadInt32(addr1) - self.ReadInt32(addr2))
            elif ins == __MULTIPLY__:
                self.WriteInt32(dest, self.ReadInt32(addr1) * self.ReadInt32(addr2))
            elif ins == __DIVIDE__:
                self.WriteInt32(dest, self.ReadInt32(addr1) / self.ReadInt32(addr2))
                
    # Gets a byte from the program
    def GetByte(self, pointer):
        return self.program[self.pointer]

    # Incress the pointer by one
    def IncPointer(self, n):
        self.pointer = self.pointer + n

    # Reads from the stream buffer
    def ReadStream(self, index, i):
        if i == __PROGRAM__:
            return self.program[index]
        elif i == __STREAM__:
            return self.stream[index]

    # Writes to the stream buffer
    def WriteStream(self, index, data):
        if i == __PROGRAM__:
            self.program[index] = data and 0xFF
        elif i == __STREAM__:
            self.stream[index] = data and 0xFF

    # Converts bytes from stream to int32
    def ReadInt32(self, index):
        _int = self.stream[index+3]
        _int = _int | self.stream[index+2] << 8
        _int = _int | self.stream[index+1] << 16
        _int = _int | self.stream[index] << 24
        return _int

    # Converts bytes from stream to int16
    def ReadInt16(self, index):
        _int = self.stream[index+1]
        _int = _int | self.stream[index] << 8
        return _int

    # Converts int32 to stream buffer
    def WriteInt32(self, index, data):
        self.stream[index+3] = (data and 0xff)
        self.stream[index+2] = (data>>8 and 0xff)
        self.stream[index+1] = (data>>16 and 0xff)
        self.stream[index]   = (data>>24 and 0xff)

    # Converts int16 to stream buffer
    def ReadInt16(self, index, data):
        self.stream[index+1] = (data and 0xff)
        self.stream[index]   = (data>>8 and 0xff)

